﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Collections;

namespace LinqToDB.Provider
{
    /// <summary>
    /// 用于组合表达式
    /// </summary>
    /// <typeparam name="T">查询的元素类型</typeparam>
    class DataQuery<T>:IQueryable<T>,IQueryable,IQueryProvider
    {
        /// <summary>
        /// 上次查询结束时的表达式
        /// </summary>
        Expression m_expression;
        /// <summary>
        /// 数据源
        /// </summary>
        SqlProvider m_provider;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="provider">数据源</param>
        /// <param name="expression">上次查询结束时的表达式</param>
        public DataQuery(SqlProvider provider, Expression expression)
        {
            this.m_provider = provider;
            this.m_expression = expression;
        }

        /// <summary>
        /// 在原查询的基础上创建新查询
        /// </summary>
        /// <typeparam name="TElement">查询元素类型</typeparam>
        /// <param name="expression">新表达式（包含了旧表达式部分）</param>
        /// <returns>新的查询接口</returns>
        public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
        {
            return new DataQuery<TElement>(m_provider, expression);
        }
        /// <summary>
        /// 在原查询的基础上创建新查询（未指定类型）
        /// </summary>
        /// <param name="expression">新表达式（包含了旧表达式部分）</param>
        /// <returns>新的查询接口</returns>
        public IQueryable CreateQuery(Expression expression)
        {
            return (IQueryable)Activator.CreateInstance(typeof(DataQuery<>).MakeGenericType(expression.Type),
                m_provider,expression);
        }

        /// <summary>
        /// 对原查询的结果执行命令, 返回常量
        /// </summary>
        /// <typeparam name="TResult">结果的类型</typeparam>
        /// <param name="expression">命令表达式</param>
        /// <returns>常量</returns>
        public TResult Execute<TResult>(Expression expression)
        {
            return (TResult)m_provider.Execute(this.m_expression);
        }

        /// <summary>
        /// 对原查询的结果执行命令, 返回常量
        /// </summary>
        /// <param name="expression">命令表达式</param>
        /// <returns>常量</returns>
        public object Execute(Expression expression)
        {
            return m_provider.Execute(this.m_expression);
        }

        /// <summary>
        /// 元素类型
        /// </summary>
        public Type ElementType
        {
            get { return typeof(T); }
        }

        /// <summary>
        /// 原表达式
        /// </summary>
        public Expression Expression
        {
            get { return m_expression; }
        }

        /// <summary>
        /// 数据源
        /// </summary>
        public IQueryProvider Provider
        {
            get { return this; }
        }

        /// <summary>
        /// 获取查询结果数据迭代器
        /// </summary>
        /// <returns>迭代器接口</returns>
        public IEnumerator GetEnumerator()
        {
            return (IEnumerator)m_provider.Execute(this.m_expression);
        }

        /// <summary>
        /// 获取查询结果数据迭代器
        /// </summary>
        /// <returns>迭代器接口</returns>
        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            return ((IEnumerable<T>)m_provider.Execute(this.m_expression)).GetEnumerator();
        }
    }
}
